package com.runchamp;

import android.app.TaskStackBuilder;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TabHost;
import android.widget.TextView;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.loopj.android.http.RequestParams;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class RaceFinished extends ActionBarActivity implements AdapterView.OnItemClickListener {
    private Intent intentRaces;
    private String POSITION;
    private String TIME;
    private String AVERAGE_SPEED;
    private String PARTICIPANTS_NUMBER;
    private String RACE_DISTANCE;
    private String RACE_ID;
    private String CALORIES;
    private String USER;
    private String SERVER_URL = "http://runtobo.appspot.com/racefinished/updatescore";
    private String UPDATE_LIST_URL = "http://runtobo.appspot.com/liverace/updatestats";
    private float estimatedTime;
    private int raceScore;
    private AsyncHttpClient client;
    private RequestParams params;
    private TextToSpeech tts;
    private BroadcastReceiver myReceiver = null;
    private Boolean myReceiverIsRegistered = false;
    private int realPos;
    private int currentTab = 0;
    private TextView score;
    /*List tab*/
    private ListView racesListView;
    private JSONAdapterStatsListFinished mJSONAdapter;
    /*media - sound*/
    private MediaPlayer applause;
    private MediaPlayer championSong;
    private MediaPlayer failSound;
    private MediaPlayer looseSong;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
          /*fields initialize*/
        setContentView(R.layout.activity_race_finished);
        applause = MediaPlayer.create(this, R.raw.applause);
        championSong = MediaPlayer.create(this, R.raw.championsong);
        failSound = MediaPlayer.create(this, R.raw.failsound);
        looseSong = MediaPlayer.create(this, R.raw.loosersong);
        POSITION = getIntent().getStringExtra("position");
        TIME = getIntent().getStringExtra("time");
        AVERAGE_SPEED = getIntent().getStringExtra("averageSpeed");
        PARTICIPANTS_NUMBER = getIntent().getStringExtra("participantsNumber");
        RACE_DISTANCE = getIntent().getStringExtra("distance");
        CALORIES = String.format("%.0f", Float.parseFloat(getIntent().getStringExtra("calories")));
        USER = getIntent().getStringExtra("user");
        RACE_ID = getIntent().getStringExtra("raceID");
        intentRaces = new Intent(this, ChooseRace.class);
        TextView time = (TextView) findViewById(R.id.time_value);
        time.setText(String.format("%02d", Integer.parseInt(TIME) / 3600) + ":" + String.format("%02d", Integer.parseInt(TIME) / 60) + ":" + String.format("%02d", Integer.parseInt(TIME) % 60));
        TextView position = (TextView) findViewById(R.id.position_value);
        realPos = Integer.valueOf(POSITION);
        /*real position starts from 1 and not from 0*/
        realPos++;
        score = (TextView) findViewById(R.id.racescore);
        String realPosStr = String.valueOf(realPos);
        position.setText(realPosStr + "/" + PARTICIPANTS_NUMBER);
        TextView distance = (TextView) findViewById(R.id.distance_value);
        distance.setText(String.format("%.2f", Float.parseFloat(RACE_DISTANCE)));
        TextView calories = (TextView) findViewById(R.id.calories_value);
        calories.setText(String.format("%.2f", Float.parseFloat(CALORIES)));
        TextView avgSpeed = (TextView) findViewById(R.id.speed_value);
        avgSpeed.setText(String.format("%.2f", Float.parseFloat(AVERAGE_SPEED)));
        ImageView fat = (ImageView) findViewById(R.id.fat);
        setVolumeControlStream(AudioManager.STREAM_MUSIC);
        /*counts in milliseconds and not seconds*/
        estimatedTime = Float.parseFloat(getIntent().getStringExtra("Estimated")) * 60.0f;
        raceScore = calcScore();
        score.setText(String.valueOf(raceScore));
        client = new AsyncHttpClient();
        params = new RequestParams();
        params.put("userID", USER);
        params.put("score", String.valueOf(raceScore));
        params.put("raceID", RACE_ID);

        /*sends data to the server about this race*/
        client.post(SERVER_URL, params, new JsonHttpResponseHandler() {
            @Override
            public void onSuccess(JSONObject response) {
            }
        });

        /*chooses what audio to play*/
        if (realPos == 1) {
            championSong.setVolume(0.4f, 0.4f);
            championSong.start();
        } else if (realPos == Integer.parseInt(PARTICIPANTS_NUMBER)) {
            looseSong.setVolume(0.4f, 0.4f);
            looseSong.start();
        } else {
            applause.setVolume(0.4f, 0.4f);
            applause.start();
        }

        /*sets the image to be shown*/
        if (realPos == 1) {
            fat.setImageResource(R.drawable.trophy);
        } else if (realPos == Integer.parseInt(PARTICIPANTS_NUMBER)) {
            fat.setImageResource(R.drawable.fat);
        } else {
            fat.setImageResource(R.drawable.thumbs_up);
        }

        /*tabs set up*/
        final TabHost tabs = (TabHost) findViewById(R.id.race_finished_tab_host);
        tabs.setup();
        TabHost.TabSpec spec = tabs.newTabSpec("My Summary");
        spec.setContent(R.id.finished_tab1);
        TabHost.TabSpec spec2 = tabs.newTabSpec("Rivals");
        spec2.setContent(R.id.finished_tab2);
        spec.setIndicator("My Summary", getResources().getDrawable(R.drawable.abc_btn_check_material));
        spec2.setIndicator("Positions", getResources().getDrawable(R.drawable.abc_btn_check_material));
        tabs.addTab(spec);
        tabs.addTab(spec2);
        tabs.setCurrentTab(0);
        tabs.setOnTabChangedListener(new AnimatedTabHostListener(tabs));
        TextView tv = (TextView) tabs.getTabWidget().getChildAt(0).findViewById(android.R.id.title); //Unselected Tabs
        tv.setTextColor(Color.parseColor("#ffffff"));
        tv = (TextView) tabs.getTabWidget().getChildAt(1).findViewById(android.R.id.title); //Unselected Tabs
        tv.setTextColor(Color.parseColor("#ffffff"));
        LinearLayout container = (LinearLayout) findViewById(R.id.RacedFinishedContainer);
        container.setOnTouchListener(new OnSwipeTouchListener(getApplicationContext()) {
            public void onSwipeRight() {
                if (currentTab == 1) {
                    tabs.setCurrentTab(0);
                    currentTab = 0;
                }
            }

            public void onSwipeLeft() {
                if (currentTab == 0) {
                    tabs.setCurrentTab(1);
                    currentTab = 1;
                }
            }

            public boolean onTouch(View v, MotionEvent event) {
                return gestureDetector.onTouchEvent(event);
            }
        });

        /*Jason set up*/
        mJSONAdapter = new JSONAdapterStatsListFinished(this, getLayoutInflater());
        if (mJSONAdapter != null) {

            racesListView = (ListView) findViewById(R.id.listView);
            racesListView.setAdapter(mJSONAdapter);
            racesListView.setOnItemClickListener(this);
        }

        IntentFilter racerFinishedFilter = new IntentFilter();
        racerFinishedFilter.addAction("com.runchamp.RACER_FINISHED");

        /*broadcasting set up*/
        registerReceiver(myReceiver, racerFinishedFilter);
        myReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                updateRaceStats();
            }
        };
        updateRaceStats();

        final int finalRealPos = realPos;
        tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() {

            @Override
            public void onInit(int status) {
                // TODO Auto-generated method stub
                if (status == TextToSpeech.SUCCESS) {
                    tts.setSpeechRate(0.9f);
                    int result = tts.setLanguage(Locale.UK);

                    if (result == TextToSpeech.LANG_MISSING_DATA ||
                            result == TextToSpeech.LANG_NOT_SUPPORTED) {
                        Log.e("error", "This Language is not supported");
                    } else {
                        String positionSpeech = String.valueOf(Integer.valueOf(POSITION) + 1);
                        if (finalRealPos == 1)
                            positionSpeech = "you are in the First place.";
                        else if (finalRealPos == Integer.parseInt(PARTICIPANTS_NUMBER))
                            positionSpeech = "you are last.";
                        else if (finalRealPos == 2)
                            positionSpeech = "you are in the Second place.";
                        else if (finalRealPos == 3)
                            positionSpeech = "you are in the Third place.";
                        else
                            positionSpeech = "your position is " + String.valueOf(finalRealPos + 1) + ".  ";
                        String stausFinished = "congratulations you completed the race ";
                        if (Integer.parseInt(getIntent().getStringExtra("finishedAllRace")) == 0)
                            stausFinished = "you did not complete the race. ";
                        ConvertTextToSpeech(stausFinished + "   " + positionSpeech + "  " + " distance covered " + distanceFloatToString(Float.parseFloat(RACE_DISTANCE)) + " you earned " + String.valueOf(raceScore) + " points");

                    }
                } else
                    Log.e("error", "Initilization Failed!");
            }
        });
    }

    public String distanceFloatToString(float dist) {
        String res;
        if (dist < 1) {

            int temp = (int) (dist * 100); //meters
            return String.valueOf(temp * 10) + "  meters.";
        } else {
            return String.format("%.1f", dist) + " kilometers.";
        }
    }

    /*calculates the scoring of this race*/
    private int calcScore() {
        double paceSuccess = (estimatedTime - Double.valueOf(TIME)) / estimatedTime;
        int pos = realPos;
        int numOfParticipants = Integer.parseInt(PARTICIPANTS_NUMBER);
        float distanceCovered = Float.parseFloat(RACE_DISTANCE);
        int finishedAllRace = Integer.parseInt(getIntent().getStringExtra("finishedAllRace"));

        float res = 0;
        res += 1; //each participant get 1 point minimum
        res += 4 * finishedAllRace; //bonus if finished all the race
        res += distanceCovered * 15; // bonus for longer distance
        if (paceSuccess > 0) { //bonus if finished before the time estimation if complete all race
            res += 5 * finishedAllRace;
        }
        ;
        if (paceSuccess > 0) {
            res += (paceSuccess * 10) * finishedAllRace; // bonus (or minus) comparing the actual time to estimated time
        }
        res += (distanceCovered + 1) * ((numOfParticipants - (pos)) * 5); // bonus for relative position (winner = max pints)
        if (((Double.valueOf((TIME)) / 60) / (Double.valueOf(RACE_DISTANCE) + 0.005)) < 6) { //bonus for high pace runners
            res += (distanceCovered) * (8 - ((Double.valueOf((TIME)) / 60) / (Double.valueOf(RACE_DISTANCE) + 0.005)));
        }
        return Math.max(Math.round(res), 0); //if less than 0 (because of bad pace) return 0
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_race_finished, menu);
        return true;
    }

    /* this performs the actual speaknig*/
    private void ConvertTextToSpeech(String str) {
        // TODO Auto-generated method stub

        if (str == null || "".equals(str)) {
            str = "Content not available";
            tts.speak(str, TextToSpeech.QUEUE_FLUSH, null);
        } else
            tts.speak(str, TextToSpeech.QUEUE_FLUSH, null);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public void backToPersonalZoneNoView() {
        //  Button b = (Button) view;
        intentRaces.putExtra("user", getIntent().getStringExtra("user"));
        tts.stop();
        tts.shutdown();
        //finish();
        Intent personalZoneIntent = new Intent(this, PersonalZone.class);
        personalZoneIntent.putExtra("user", getIntent().getStringExtra("user"));

        TaskStackBuilder.create(this)
                .addNextIntent(new Intent(this, MyRaces.class))
                .addNextIntent(new Intent(this, PersonalZone.class))
                .startActivities();

        finish();
    }

    public void backToPersonalZone(View view) {
        backToPersonalZoneNoView();
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

    }

    @Override
    public void onResume() {
        super.onResume();
        if (!myReceiverIsRegistered) {
            IntentFilter updateReadyFilter = new IntentFilter();
            updateReadyFilter.addAction("com.runchamp.RACER_FINISHED");
            registerReceiver(myReceiver, updateReadyFilter);
            myReceiverIsRegistered = true;
        }

    }

    @Override
    protected void onPause() {
        super.onPause();
        if (myReceiverIsRegistered) {
            unregisterReceiver(myReceiver);
            myReceiverIsRegistered = false;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (myReceiverIsRegistered) {
            unregisterReceiver(myReceiver);
            myReceiverIsRegistered = false;
        }
    }


    public void updateRaceStats() {
        final List<CurrentStats> statsList = new ArrayList<CurrentStats>();
        client.get(UPDATE_LIST_URL + "?raceID=" + RACE_ID,
                new JsonHttpResponseHandler() {

                    @Override
                    public void onSuccess(JSONArray jsonArray) {
                        mJSONAdapter.updateData(jsonArray);

                    }

                    @Override
                    public void onFailure(int statusCode, Throwable throwable, JSONObject error) {
                    }
                });
    }


    @Override
    public void onBackPressed() {
        backToPersonalZoneNoView();
    }
}
